package gui.scene;

import java.awt.Graphics2D;
import java.util.HashMap;
import java.util.LinkedList;

import util.Logger;
import core.ViewableEntity;

/**
 * Consists of layers such as: <br>
 * Image Layers (a static or repeated image) <br>
 * Tile Layers (from a tile-set) <br>
 * Entity Layers (contain player characters & world objects) <br>
 * Particle Layers (for displaying particle effects) <br>
 * Custom Layers (additional types can be created by you) <br>
 * 
 * @author Jason
 * 
 */
public class LayeredScene extends Scene {

	/**
	 * Maps layerIDs to layers.
	 */
	protected final HashMap<Byte, Layer> layerHash = new HashMap<Byte, Layer>();

	protected LinkedList<Layer> layers = new LinkedList<Layer>();

	/**
	 * Adds a layer to be rendered last.
	 */
	public synchronized void addToFront(Layer layer, byte layerID) {
		layers.addLast(layer);
		layerHash.put(layerID, layer);
	}

	/**
	 * Adds a layer to be rendered first.
	 */
	public synchronized void addToBack(Layer layer, byte layerID) {
		layers.addFirst(layer);
		layerHash.put(layerID, layer);
	}

	/**
	 * Adds a layer at the specified index.
	 * 
	 * @param index
	 *            A high index = later rendering = closer to the front
	 */
	public synchronized void add(Layer layer, byte layerID, int index) {
		layers.add(index, layer);
		layerHash.put(layerID, layer);
	}

	/**
	 * Renders the scene onto the specified pixel area.
	 */
	@Override
	protected synchronized void renderScene(Graphics2D g) {
		for (Layer layer : layers) {
			layer.render(worldViewArea, g);
		}
	}

	@Override
	public synchronized void addEntity(ViewableEntity e) {
		Layer layer = layerHash.get(e.layer);
		if (layer == null) {
			Logger.log(Logger.WARNING,
					"Tried to add entity to layer which does not exist.");
			return;
		}
		if (layer instanceof EntityLayer == false) {
			Logger.log(Logger.WARNING,
					"Entities can only be added to EntityLayers.");
			return;
		}
		EntityLayer eLayer = (EntityLayer) layer;
		eLayer.addEntity(e);
	}

}
